
/*
 * Copyright (C) 2008-2009 Archie L. Cobbs. All rights reserved.
 *
 * $Id: AbstractSchemaUpdate.java 377 2010-03-11 20:50:18Z archie.cobbs $
 */

package org.dellroad.sidekar.schema.change;

import org.dellroad.sidekar.schema.SchemaModificationException;
import org.dellroad.sidekar.schema.model.EntityModel;
import org.dellroad.sidekar.schema.model.SchemaModel;

/**
 * {@link SchemaChange} that removes an entity from the schema.
 *
 * <p>
 * This automatically removes all indexes associated with the entity and all instances of the entity.
 * All references to instances of this entity by any other entities will become detached.
 * </p>
 *
 * <p>
 * The entity must not be the parent of any other entities, and there must be no reference fields in
 * other entities that refer <i>directly</i> to this entity (references to one of this entity's ancestor
 * entities are allowed).
 * </p>
 */
public class RemoveEntityChange extends EntityChange {

    /**
     * Constructor.
     *
     * @param entityName name of the entity to remove
     * @throws IllegalArgumentException if {@code entityName} is not a legal entity name
     */
    public RemoveEntityChange(String entityName) {
        super(entityName);
    }

    @Override
    public String getDescription() {
        return "remove entity `" + this.getEntityName() + "'";
    }

    @Override
    public void checkValidFor(SchemaModel schemaModel) {
        super.checkValidFor(schemaModel);

        // Verify entity is a leaf
        EntityModel entityModel = this.checkEntityExists(schemaModel, this.getEntityName());
        for (EntityModel otherEntityModel : schemaModel.getEntityModels().values()) {
            if (otherEntityModel.getParentModel() == entityModel) {
                throw new SchemaModificationException("can't remove " + entityModel
                    + " because it is a parent of " + otherEntityModel + " (it must be removed first)");
            }
        }
    }

    @Override
    public final void visit(SchemaChangeSwitch schemaChangeSwitch) {
        schemaChangeSwitch.caseRemoveEntityChange(this);
    }
}

